<!-- 单个消息项组件 -->
<template>
	<div class="message-wrapper" :class="message.role">
		<div class="message-bubble">
			<div class="message-avatar">
				<a-avatar v-if="message.role === 'user'" :src="computedUserAvatar" class="message-avatar-style">
					{{ userName?.[0]?.toUpperCase() }}
				</a-avatar>
				<a-avatar v-else :src="logoImg" :size="36" class="message-avatar-style"></a-avatar>
			</div>
			<div class="message-content">
				<!-- 渲染解析后的内容块 -->
				<div class="content-blocks">
					<template v-for="(block, index) in parsedContent" :key="index">
						<!-- 文本内容块 -->
						<div v-if="block.type === 'text'" class="text-block" v-html="block.content"></div>
						<!-- 代码卡片块 -->
						<CodeCard
							v-else-if="block.type === 'code'"
							:file-name="block.fileName"
							:code-content="block.content"
							:language="block.language"
							@click="handleCodeCardClick"
						/>
						<!-- 元素修改卡片块 -->
						<div v-else-if="block.type === 'element-card'" class="element-modify-display">
							<!-- 用户文本正常输出 -->
							<div class="user-text-normal">
								{{ block.elementInfo?.userInput || block.content }}
							</div>
							<!-- 选中元素信息卡片 -->
							<div
								class="selected-element-card"
								v-if="block.elementInfo?.selector || block.elementInfo?.originalElement"
							>
								<div class="element-info-row">
									<span class="element-tag">{{ extractTagFromSelector(block.elementInfo?.selector) }}</span>
									<span class="element-class" v-if="extractClassFromSelector(block.elementInfo?.selector)">{{ extractClassFromSelector(block.elementInfo?.selector) }}</span>
									<span class="element-content">{{ block.elementInfo?.textContent || block.elementInfo?.originalElement }}</span>
								</div>
							</div>
						</div>
						<!-- 多元素修改卡片块 -->
						<MultiElementContainer
							v-else-if="block.type === 'multi-element-card'"
							:user-request="block.userRequest"
							:elements="block.elements"
						/>
					</template>
				</div>
				<div class="message-time">{{ formatTime(message.timestamp) }}</div>
			</div>
		</div>

		<!-- 代码查看器 -->
		<CodeViewer
			v-model:open="codeViewerVisible"
			:file-name="selectedCode.fileName"
			:code-content="selectedCode.content"
			:language="selectedCode.language"
			@close="handleCodeViewerClose"
		/>
	</div>
</template>

<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue'
import { marked } from 'marked'
import dayjs from 'dayjs'
import logoImg from '@/assets/logo.png'
import kunkunImg from '@/assets/kunkun.png'
import { setupMarkdownRenderer } from '@/utils/markdownRenderer'
import CodeCard from '@/components/common/CodeCard.vue'
import { CodeViewer } from '@/components/app'
import MultiElementContainer from './MultiElementContainer.vue'

interface Message {
	id?: number
	role: 'user' | 'assistant'
	content: string
	timestamp: Date
	isHistoryMessage?: boolean
	_updateKey?: number // 添加更新键类型定义
}

interface Props {
	message: Message
	userAvatar?: string
	userName?: string
}

const props = defineProps<Props>()

// 计算用户头像，如果没有头像则使用kunkun.png作为默认
const computedUserAvatar = computed(() => {
	return props.userAvatar || kunkunImg
})

// 代码查看器相关状态
const codeViewerVisible = ref(false)
const selectedCode = ref({
	fileName: '',
	content: '',
	language: '',
})

// 内容块类型定义
interface ContentBlock {
	type: 'text' | 'code' | 'element-card' | 'multi-element-card'
	content: string
	fileName?: string
	language?: string
	// 元素卡片相关属性
	elementInfo?: {
		action: string // 修改动作描述
		target: string // 目标内容
		originalElement?: string // 原始元素内容
		selector?: string // 选择器
		userInput?: string // 用户实际输入
		systemInfo?: string // 系统补充信息
		textContent?: string // 提取的文本内容
	}
	// 多元素卡片相关属性
	elements?: Array<{
		action: string
		target: string
		originalElement?: string
		selector?: string
		userInput?: string
		systemInfo?: string
		textContent?: string
	}>
	userRequest?: string
}

// 配置marked渲染器
const renderer = setupMarkdownRenderer()
marked.setOptions({
	renderer,
	breaks: true,
	gfm: true,
})

// 解析消息内容，提取代码块并转换为卡片
const parsedContent = computed(() => {
	const content = props.message.content
	if (!content) return []

	const blocks: ContentBlock[] = []

	// 如果是用户消息，检查是否包含元素修改请求
	if (props.message.role === 'user') {
		// 首先尝试多元素检测
		const multiElementMatch = detectMultiElementModifyRequest(content)
		if (multiElementMatch && multiElementMatch.elements.length > 0) {
			// 创建一个父容器卡片包含所有元素
			blocks.push({
				type: 'multi-element-card',
				content: content,
				elements: multiElementMatch.elements,
				userRequest: multiElementMatch.userInput
			})
			return blocks
		}

		// 回退到单元素检测（向后兼容）
		const elementModifyMatch = detectElementModifyRequest(content)
		if (elementModifyMatch) {
			blocks.push({
				type: 'element-card',
				content: content,
				elementInfo: elementModifyMatch,
			})
			return blocks
		}
	}

	// 使用正则表达式匹配代码块
	const codeBlockRegex = /```(\w+)?\s*([\s\S]*?)```/g
	let lastIndex = 0
	let match

	while ((match = codeBlockRegex.exec(content)) !== null) {
		// 添加代码块前的文本内容
		if (match.index > lastIndex) {
			const textContent = content.slice(lastIndex, match.index)
			if (textContent.trim()) {
				blocks.push({
					type: 'text',
					content: processTextContent(textContent),
				})
			}
		}

		// 添加代码块
		let language = match[1] || 'text'
		const codeContent = match[2].trim()

		// 标准化语言名称
		language = normalizeLanguage(language)

		// 从消息上下文中提取文件名
		const fileName = extractFileNameFromContext(content, match.index, codeContent, language)

		blocks.push({
			type: 'code',
			content: codeContent,
			fileName,
			language,
		})

		lastIndex = codeBlockRegex.lastIndex
	}

	// 添加最后剩余的文本内容
	if (lastIndex < content.length) {
		const textContent = content.slice(lastIndex)
		if (textContent.trim()) {
			blocks.push({
				type: 'text',
				content: processTextContent(textContent),
			})
		}
	}

	// 如果没有代码块，返回整个内容作为文本
	if (blocks.length === 0) {
		blocks.push({
			type: 'text',
			content: processTextContent(content),
		})
	}

	return blocks
})

// 处理文本内容（应用markdown渲染和工具消息样式）
const processTextContent = (text: string): string => {
	try {
		let processedContent = marked.parse(text) as string

		// 处理括号内的HTML内容，避免CSS渲染
		// 匹配 [<tag>content</tag>] 格式，将其转换为纯文本显示
		processedContent = processedContent.replace(/\[(<[^>]+>[^<]*<\/[^>]+>)\]/g, (match, htmlContent) => {
			// 将HTML标签转义，避免被浏览器渲染
			const escapedHtml = htmlContent.replace(/</g, '&lt;').replace(/>/g, '&gt;')
			return `[<code class="inline-html">${escapedHtml}</code>]`
		})

		// 使用更宽松的工具消息匹配规则，支持更多格式变体
		// 处理选择工具消息: **🔧 [选择工具]** xxx ⚡ 或 **🔧 [选择工具]** xxx
		processedContent = processedContent.replace(
			/<p><strong>🔧\s*\[选择工具\]<\/strong>\s*(.*?)(?:\s*⚡)?<\/p>/g,
			(match, content) => {
				// 检查是否包含⚡符号，如果不包含则添加转圈样式（表示正在选择）
				const hasLightning = match.includes('⚡')
				const className = hasLightning ? 'tool-modify-msg' : 'tool-selecting-msg'
				return `<p class="${className}"><strong>🔧 [选择工具]</strong> ${content.trim()}</p>`
			}
		)

		// 处理各种工具调用结果消息，使用更宽松的匹配
		// 删除文件: **🗑️ [工具调用]** 或类似格式
		processedContent = processedContent.replace(
			/<p><strong>🗑️\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-delete-msg"><strong>🗑️ [工具调用]</strong> $1</p>'
		)

		// 读取目录: **🗂️ [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>🗂️\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-folder-msg"><strong>🗂️ [工具调用]</strong> $1</p>'
		)

		// 修改文件: **🔧 [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>🔧\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-modify-msg"><strong>🔧 [工具调用]</strong> $1</p>'
		)

		// 读取文件: **📖 [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>📖\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-read-msg"><strong>📖 [工具调用]</strong> $1</p>'
		)

		// 写入文件: **✏️ [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>✏️\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-write-msg"><strong>✏️ [工具调用]</strong> $1</p>'
		)

		// 退出工具: **🏁 [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>🏁\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-exit-msg"><strong>🏁 [工具调用]</strong> $1</p>'
		)

		// 搜索代码库: **🔍 [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>🔍\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-search-msg"><strong>🔍 [工具调用]</strong> $1</p>'
		)

		// 运行命令: **⚡ [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>⚡\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-command-msg"><strong>⚡ [工具调用]</strong> $1</p>'
		)

		// 兼容旧的工具调用格式: **✅ [工具调用]**
		processedContent = processedContent.replace(
			/<p><strong>✅\s*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-default-msg"><strong>✅ [工具调用]</strong> $1</p>'
		)

		// 通用工具调用格式匹配 - 作为兜底方案
		processedContent = processedContent.replace(
			/<p><strong>[^<]*\[工具调用\]<\/strong>\s*(.*?)<\/p>/g,
			'<p class="tool-default-msg"><strong>🔧 [工具调用]</strong> $1</p>'
		)

		return processedContent
	} catch (error) {
		console.error('Markdown解析失败:', error)
		return text.replace(/\n/g, '<br>')
	}
}

// 检测多个元素修改请求
const detectMultiElementModifyRequest = (content: string) => {
	// 检查是否包含修改相关的关键词
	const modifyKeywords = ['修改为', '改为', '改成', '更改为', '修改', '改', '删除', '移除', '去掉', '隐藏', '显示', '添加', '增加']
	const hasModifyKeyword = modifyKeywords.some((keyword) => content.includes(keyword))

	if (!hasModifyKeyword) {
		return null
	}

	// 分离用户输入和系统补充信息
	const systemInfoSeparator = '需要修改的元素：'
	let userInput = content
	let elements = []

	if (content.includes(systemInfoSeparator)) {
		const parts = content.split(systemInfoSeparator)
		let rawUserInput = parts[0].trim()

		// 智能提取真正的用户输入，过滤掉预设内容
		userInput = extractRealUserInput(rawUserInput)

		// 处理每个元素部分
		for (let i = 1; i < parts.length; i++) {
			const elementSection = systemInfoSeparator + parts[i]
			const elementInfo = parseElementSection(elementSection, userInput)
			if (elementInfo) {
				elements.push(elementInfo)
			}
		}
	}

	return elements.length > 0 ? { elements, userInput } : null
}

// 解析单个元素部分
const parseElementSection = (elementSection: string, userInput: string) => {
	// 提取HTML元素
	const htmlMatch = elementSection.match(/\[([^\]]+)\]/)
	if (!htmlMatch) return null

	const originalElement = htmlMatch[1]

	// 从用户输入中匹配修改请求模式
	const patterns = [
		// 匹配 "修改为xxx" 或 "改为xxx" 或 "改成xxx"
		/(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n]+)[""']?/,
		// 匹配 "把xxx修改为yyy" 或 "将xxx改为yyy"
		/(?:把|将)\s*(.+?)\s*(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n]+)[""']?/,
		// 匹配 "xxx修改为yyy" 或 "xxx改为yyy"
		/(.+?)\s*(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n]+)[""']?/,
	]

	let action = '修改为'
	let target = ''

	for (const pattern of patterns) {
		const match = userInput.match(pattern)
		if (match) {
			if (pattern === patterns[0]) {
				target = match[1].trim()
			} else {
				target = match[2].trim()
			}
			break
		}
	}

	return {
		action,
		target,
		originalElement,
		textContent: extractTextFromElement(elementSection),
		selector: extractSelectorFromContent(elementSection),
		userInput,
		systemInfo: elementSection,
	}
}

// 检测元素修改请求（保持向后兼容）
const detectElementModifyRequest = (content: string) => {
	// 首先尝试多元素检测
	const multiResult = detectMultiElementModifyRequest(content)
	if (multiResult && multiResult.elements.length > 0) {
		// 如果是多元素，返回第一个元素（保持兼容性）
		return multiResult.elements[0]
	}

	// 原有的单元素检测逻辑
	// 检查是否包含修改相关的关键词
	const modifyKeywords = ['修改为', '改为', '改成', '更改为', '修改', '改', '删除', '移除', '去掉', '隐藏', '显示', '添加', '增加']
	const hasModifyKeyword = modifyKeywords.some((keyword) => content.includes(keyword))

	if (!hasModifyKeyword) {
		return null
	}

	// 分离用户输入和系统补充信息
	// 系统补充信息通常以"需要修改的元素："开始
	const systemInfoSeparator = '需要修改的元素：'
	let userInput = content
	let systemInfo = ''

	if (content.includes(systemInfoSeparator)) {
		const parts = content.split(systemInfoSeparator)
		userInput = parts[0].trim()
		systemInfo = systemInfoSeparator + parts.slice(1).join(systemInfoSeparator)
	}

	// 从用户输入中匹配修改请求模式
	const patterns = [
		// 匹配 "修改为xxx" 或 "改为xxx" 或 "改成xxx"
		/(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n]+)[""']?/,
		// 匹配 "把xxx修改为yyy" 或 "将xxx改为yyy"
		/(?:把|将)\s*(.+?)\s*(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n]+)[""']?/,
		// 匹配 "xxx修改为yyy" 或 "xxx改为yyy"
		/(.+?)\s*(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n]+)[""']?/,
		// 匹配 "修改h1标签为现代化博客"
		/修改\s*(.+?)\s*为\s*[""']?([^""'\n]+)[""']?/,
	]

	for (const pattern of patterns) {
		// 只在用户输入部分进行匹配
		const match = userInput.match(pattern)
		if (match) {
			let action, target, originalElement

			if (pattern === patterns[0]) {
				// 简单的 "修改为xxx" 模式
				action = '修改为'
				target = match[1].trim()
				// 从系统信息中提取原始元素信息
				originalElement = extractOriginalElementFromContent(systemInfo || content)
			} else if (pattern === patterns[1]) {
				// "把xxx修改为yyy" 模式
				action = '修改为'
				originalElement = match[1].trim()
				target = match[2].trim()
			} else if (pattern === patterns[2]) {
				// "xxx改为yyy" 模式
				action = '修改为'
				originalElement = match[1].trim()
				target = match[2].trim()
			} else if (pattern === patterns[3]) {
				// "修改xxx为yyy" 模式
				action = '修改为'
				originalElement = match[1].trim()
				target = match[2].trim()
			}

			return {
				action,
				target,
				originalElement,
				textContent: extractTextFromElement(systemInfo || content), // 添加文本内容字段
				selector: extractSelectorFromContent(systemInfo || content),
				userInput: userInput, // 添加用户输入字段
				systemInfo: systemInfo, // 添加系统信息字段
			}
		}
	}

	return null
}

// 智能提取真正的用户输入，过滤掉预设内容
const extractRealUserInput = (rawInput: string): string => {
	// 如果输入包含HTML标签和样式，很可能是预设内容，需要进一步处理
	if (rawInput.includes('<div style=') || rawInput.includes('background:') || rawInput.includes('border:')) {
		// 方法1: 尝试提取修改关键词及其目标内容
		const modifyPatterns = [
			// 匹配 "修改为xxx" 格式
			/(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n<>]{1,30})[""']?/,
			// 匹配 "把xxx修改为yyy" 格式，提取yyy
			/(?:把|将)\s*[^修改]{1,20}\s*(?:修改为|改为|改成|更改为)\s*[""']?([^""'\n<>]{1,30})[""']?/,
			// 匹配简单的修改意图
			/(修改|改|删除|移除|添加|增加|隐藏|显示)\s*[^<>]{0,20}/
		]

		for (const pattern of modifyPatterns) {
			const match = rawInput.match(pattern)
			if (match) {
				const extracted = match[1] || match[0]
				// 确保提取的内容不包含HTML标签且长度合理
				if (extracted && !extracted.includes('<') && !extracted.includes('style=') && extracted.length < 50) {
					return extracted.trim()
				}
			}
		}

		// 方法2: 查找纯中文的简短描述（在HTML标签之外）
		const cleanTextMatch = rawInput.match(/^([^<>]{1,30}(?:修改|改|删除|移除|添加|增加|隐藏|显示)[^<>]{0,20})(?=<|$)/)
		if (cleanTextMatch) {
			return cleanTextMatch[1].trim()
		}

		// 方法3: 如果都没找到，尝试提取最前面的简洁中文文本
		const frontTextMatch = rawInput.match(/^([\u4e00-\u9fa5\s]{1,20})(?=<|需要修改的元素)/)
		if (frontTextMatch && frontTextMatch[1].trim().length > 0) {
			return frontTextMatch[1].trim()
		}

		// 方法4: 最后兜底，返回一个通用的描述
		return '修改页面元素'
	}

	// 如果不包含预设内容标识，直接返回原输入
	return rawInput
}

// 从内容中提取文本内容
const extractTextFromElement = (content: string): string => {
	// 尝试从完整HTML标签中提取文本内容
	const fullHtmlMatch = content.match(/<[^>]*>([\s\S]*?)<\/[^>]*>/)
	if (fullHtmlMatch && fullHtmlMatch[1]) {
		return fullHtmlMatch[1].replace(/<[^>]*>/g, '').trim() // 移除内部HTML标签
	}

	// 尝试提取简单的HTML标签内文本
	const simpleHtmlMatch = content.match(/>([^<]+)</)
	if (simpleHtmlMatch) {
		return simpleHtmlMatch[1].trim()
	}

	return ''
}

// 从内容中提取原始元素信息
const extractOriginalElementFromContent = (content: string): string => {
	// 尝试提取引号内的内容
	const quotedMatch = content.match(/[""']([^""']+)[""']/)
	if (quotedMatch) {
		return quotedMatch[1]
	}

	// 尝试提取HTML标签内的文本内容（支持多层嵌套）
	const htmlMatch = content.match(/<[^>]+>([^<]*)<\/[^>]+>/)
	if (htmlMatch && htmlMatch[1]) {
		return htmlMatch[1].trim()
	}

	// 尝试提取简单的HTML标签内文本
	const simpleHtmlMatch = content.match(/>([^<]+)</)
	if (simpleHtmlMatch) {
		return simpleHtmlMatch[1].trim()
	}

	// 尝试从完整HTML标签中提取文本（如：<h1 class="site-title">我的个人博客</h1>）
	const fullHtmlMatch = content.match(/<[^>]*>([\s\S]*?)<\/[^>]*>/)
	if (fullHtmlMatch && fullHtmlMatch[1]) {
		return fullHtmlMatch[1].replace(/<[^>]*>/g, '').trim() // 移除内部HTML标签
	}

	return ''
}

// 从内容中提取选择器信息
const extractSelectorFromContent = (content: string): string => {
	// 尝试提取完整的HTML标签
	const fullHtmlMatch = content.match(/<([^\s>]+)[^>]*>/)
	if (fullHtmlMatch) {
		const tagName = fullHtmlMatch[1]

		// 尝试提取类名
		const classMatch = content.match(/class="([^"]+)"|class='([^']+)'/)
		if (classMatch) {
			const className = classMatch[1] || classMatch[2]
			const classes = className.split(' ').filter((cls) => cls && !cls.startsWith('visual-editor'))
			if (classes.length > 0) {
				return `${tagName}.${classes.join('.')}`
			}
		}

		return tagName
	}

	// 尝试提取标签名（如 "h1标签"）
	const tagMatch = content.match(/(h[1-6]|div|span|p|a|img|button|input|form|table|ul|ol|li)(?:标签)?/i)
	if (tagMatch) {
		return tagMatch[1].toLowerCase()
	}

	// 尝试提取类名或ID
	const classMatch = content.match(/class="([^"]+)"|class='([^']+)'/)
	if (classMatch) {
		const className = classMatch[1] || classMatch[2]
		const classes = className.split(' ').filter((cls) => cls && !cls.startsWith('visual-editor'))
		if (classes.length > 0) {
			return `.${classes.join('.')}`
		}
	}

	const idMatch = content.match(/id[="']([^"']+)["']/)
	if (idMatch) {
		return `#${idMatch[1]}`
	}

	return ''
}

// 标准化语言名称
const normalizeLanguage = (language: string): string => {
	const languageMap: Record<string, string> = {
		js: 'javascript',
		ts: 'typescript',
		py: 'python',
		jsx: 'javascript',
		tsx: 'typescript',
		vue: 'vue',
		html: 'html',
		css: 'css',
		scss: 'scss',
		sass: 'sass',
		less: 'less',
		json: 'json',
		xml: 'xml',
		yaml: 'yaml',
		yml: 'yaml',
		md: 'markdown',
		markdown: 'markdown',
		sh: 'bash',
		bash: 'bash',
		shell: 'bash',
		sql: 'sql',
		java: 'java',
		c: 'c',
		cpp: 'cpp',
		cxx: 'cpp',
		cc: 'cpp',
		php: 'php',
		go: 'go',
		rust: 'rust',
		rs: 'rust',
		swift: 'swift',
		kotlin: 'kotlin',
		kt: 'kotlin',
		dart: 'dart',
		r: 'r',
		ruby: 'ruby',
		rb: 'ruby',
		perl: 'perl',
		pl: 'perl',
		lua: 'lua',
		powershell: 'powershell',
		ps1: 'powershell',
		dockerfile: 'dockerfile',
		text: 'text',
		txt: 'text',
	}

	return languageMap[language.toLowerCase()] || language.toLowerCase()
}

// 从消息上下文中提取文件名
const extractFileNameFromContext = (
	fullContent: string,
	codeBlockIndex: number,
	codeContent: string,
	language: string
): string => {
	// 获取代码块前的文本内容，查找工具调用消息
	const beforeContent = fullContent.slice(0, codeBlockIndex)

	// 匹配工具调用消息中的文件路径
	// 匹配模式：**✏️ [工具调用]** 写入文件 src/App.vue
	const toolCallRegex = /\*\*[^\*]+\[工具调用\]\*\*[^\n]*(?:写入文件|修改文件|创建文件)\s+([^\s\n]+)/g
	let match
	let lastMatch = null

	// 找到最接近代码块的工具调用消息
	while ((match = toolCallRegex.exec(beforeContent)) !== null) {
		lastMatch = match
	}

	if (lastMatch && lastMatch[1]) {
		const filePath = lastMatch[1]
		// 提取文件名（去掉路径）
		const fileName = filePath.split(/[\/\\]/).pop() || filePath
		return fileName
	}

	// 如果没有找到工具调用消息，尝试从代码内容第一行提取
	const lines = codeContent.split('\n')
	const firstLine = lines[0]?.trim()

	// 检查是否包含文件路径或文件名的模式
	const filePathRegex = /(?:\/|\\)?([\w.-]+\.[\w]+)(?:\s|$)/
	const fileMatch = firstLine?.match(filePathRegex)

	if (fileMatch && fileMatch[1]) {
		return fileMatch[1]
	}

	// 根据语言生成默认文件名
	const languageExtensions: Record<string, string> = {
		javascript: 'js',
		typescript: 'ts',
		python: 'py',
		java: 'java',
		cpp: 'cpp',
		c: 'c',
		css: 'css',
		scss: 'scss',
		sass: 'sass',
		less: 'less',
		html: 'html',
		json: 'json',
		xml: 'xml',
		yaml: 'yml',
		markdown: 'md',
		bash: 'sh',
		sql: 'sql',
		vue: 'vue',
		php: 'php',
		go: 'go',
		rust: 'rs',
		swift: 'swift',
		kotlin: 'kt',
		dart: 'dart',
		ruby: 'rb',
		perl: 'pl',
		lua: 'lua',
		powershell: 'ps1',
		dockerfile: 'Dockerfile',
		text: 'txt',
	}

	const extension = languageExtensions[language] || 'txt'
	return `code.${extension}`
}

// 处理代码卡片点击事件
const handleCodeCardClick = (data: { fileName: string; codeContent: string; language?: string }) => {
	selectedCode.value = {
		fileName: data.fileName,
		content: data.codeContent,
		language: data.language || 'text',
	}
	codeViewerVisible.value = true
}

// 处理代码查看器关闭事件
const handleCodeViewerClose = () => {
	codeViewerVisible.value = false
}

// 保留原有的formattedContent以兼容可能的其他用途
const formattedContent = computed(() => {
	const content = props.message.content
	if (!content) return ''

	return processTextContent(content)
})

// 格式化时间
const formatTime = (time: Date) => {
	return dayjs(time).format('HH:mm:ss')
}

// 监听消息内容变化，处理转圈样式的移除
watch(
	() => [props.message.content, props.message._updateKey],
	() => {
		nextTick(() => {
			removeSpinnerFromCompletedTools()
		})
	},
	{ immediate: true }
)

// 移除已完成工具的转圈样式
const removeSpinnerFromCompletedTools = () => {
	const content = props.message.content
	if (!content) return

	// 检查消息是否包含工具选择但没有⚡符号（表示已完成）
	const hasToolSelecting = content.includes('🔧 [选择工具]')
	const hasLightning = content.includes('⚡')

	// 如果有工具选择消息但没有⚡符号，说明工具选择已完成
	if (hasToolSelecting && !hasLightning) {
		// 使用DOM操作移除转圈样式
		nextTick(() => {
			const toolSelectingElements = document.querySelectorAll('.tool-selecting-msg')
			toolSelectingElements.forEach((element) => {
				// 检查元素是否属于当前消息
				const messageWrapper = element.closest('.message-wrapper')
				if (messageWrapper && messageWrapper.querySelector('.message-content')) {
					// 添加completed类来移除转圈样式
					element.classList.add('completed')
				}
			})
		})
	}

	// 检查是否有其他工具调用完成的标志
	const toolCompletionPatterns = [
		/\*\*🗑️\s*\[工具调用\]\*\*/, // 删除文件完成
		/\*\*📖\s*\[工具调用\]\*\*/, // 读取文件完成
		/\*\*✏️\s*\[工具调用\]\*\*/, // 写入文件完成
		/\*\*🔧\s*\[工具调用\]\*\*/, // 修改文件完成
		/\*\*🗂️\s*\[工具调用\]\*\*/, // 读取目录完成
		/\*\*🔍\s*\[工具调用\]\*\*/, // 搜索代码库完成
		/\*\*⚡\s*\[工具调用\]\*\*/, // 运行命令完成
		/\*\*🏁\s*\[工具调用\]\*\*/, // 退出工具完成
	]

	// 如果检测到任何工具调用完成，移除所有选择工具的转圈样式
	const hasAnyToolCompletion = toolCompletionPatterns.some((pattern) => pattern.test(content))
	if (hasAnyToolCompletion) {
		nextTick(() => {
			const toolSelectingElements = document.querySelectorAll('.tool-selecting-msg')
			toolSelectingElements.forEach((element) => {
				element.classList.add('completed')
			})
		})
	}
}

// 从选择器中提取标签名
const extractTagFromSelector = (selector?: string): string => {
	if (!selector) return ''
	// 提取标签名（如 h1.site-title 中的 h1）
	const tagMatch = selector.match(/^([a-zA-Z][a-zA-Z0-9]*)/)
	return tagMatch ? tagMatch[1] : ''
}

// 从选择器中提取类名
const extractClassFromSelector = (selector?: string): string => {
	if (!selector) return ''
	// 提取类名（如 h1.site-title 中的 site-title）
	const classMatch = selector.match(/\.([a-zA-Z][a-zA-Z0-9-_]*)/)
	return classMatch ? classMatch[1] : ''
}
</script>

<style scoped lang="scss">
.message-wrapper {
	margin-bottom: 20px;

	&.user {
		display: flex;
		justify-content: flex-end;

		.message-bubble {
			max-width: 70%;
			display: flex;
			gap: 12px;
			flex-direction: row-reverse;

			.message-content {
				background: #1890ff;
				color: white;
				border-radius: 18px 4px 18px 18px;

				/* 用户消息中的代码样式调整 */
				:deep(code) {
					background-color: rgba(255, 255, 255, 0.2);
					color: #fff;
				}

				:deep(pre) {
					background-color: rgba(255, 255, 255, 0.1);

					code {
						background: none;
						color: #fff;
					}
				}
			}
		}
	}

	&.assistant {
		display: flex;
		justify-content: flex-start;

		.message-bubble {
			max-width: 80%;
			display: flex;
			gap: 12px;

			.message-content {
				background: #f6f6f6;
				color: #333;
				border-radius: 4px 18px 18px 18px;
			}
		}
	}

	.message-content {
		padding: 12px 16px;
		position: relative;

		.message-text {
			line-height: 1.6;
			word-break: break-word;

			/* Markdown样式 */
			:deep(h1),
			:deep(h2),
			:deep(h3),
			:deep(h4),
			:deep(h5),
			:deep(h6) {
				margin: 8px 0 4px 0;
				font-weight: 600;
			}

			:deep(p) {
				margin: 4px 0;

				/* 工具选择状态样式 - 紫色主题 */
				&.tool-selecting-msg {
					background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #4c63d2;
					box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
					position: relative;
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}

					&::after {
						content: '';
						position: absolute;
						right: 8px;
						top: 50%;
						transform: translateY(-50%);
						width: 16px;
						height: 16px;
						border: 2px solid #fff;
						border-top: 2px solid transparent;
						border-radius: 50%;
						animation: spin 1s linear infinite;
					}
				}

				/* 删除文件工具 - 红色主题 */
				&.tool-delete-msg {
					background: linear-gradient(135deg, #ff6b6b 0%, #ff5722 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #e53e3e;
					box-shadow: 0 2px 8px rgba(255, 107, 107, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}

				/* 读取目录工具 - 青色主题 */
				&.tool-readdir-msg {
					background: linear-gradient(135deg, #4ecdc4 0%, #44a08d 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #38b2ac;
					box-shadow: 0 2px 8px rgba(78, 205, 196, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}

				/* 修改文件工具 - 橙色主题 */
				&.tool-modify-msg {
					background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #f57c00;
					box-shadow: 0 2px 8px rgba(255, 167, 38, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}

				/* 读取文件工具 - 蓝色主题 */
				&.tool-read-msg {
					background: linear-gradient(135deg, #42a5f5 0%, #1e88e5 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #1976d2;
					box-shadow: 0 2px 8px rgba(66, 165, 245, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}

				/* 写入文件工具 - 绿色主题 */
				&.tool-write-msg {
					background: linear-gradient(135deg, #66bb6a 0%, #4caf50 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #388e3c;
					box-shadow: 0 2px 8px rgba(102, 187, 106, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}

				/* 退出工具 - 深紫色主题 */
				&.tool-exit-msg {
					background: linear-gradient(135deg, #8e44ad 0%, #9b59b6 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #7d3c98;
					box-shadow: 0 2px 8px rgba(142, 68, 173, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}

				/* 默认工具调用 - 青绿色主题 */
				&.tool-default-msg {
					background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
					color: #ffffff;
					padding: 8px 12px;
					border-radius: 8px;
					margin: 8px 0;
					border-left: 4px solid #0d7377;
					box-shadow: 0 2px 8px rgba(17, 153, 142, 0.3);
					font-weight: 600;
					text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

					strong {
						color: #ffffff !important;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
					}
				}
			}
			/* 行内代码样式 */
			:deep(code:not(.hljs)) {
				background-color: rgba(175, 184, 193, 0.2);
				color: #e36209;
				padding: 2px 6px;
				border-radius: 4px;
				font-size: 0.875em;
				font-family: 'Fira Code', 'Monaco', 'Cascadia Code', 'Roboto Mono', 'Consolas', 'Courier New', monospace;
				font-weight: 500;
				border: 1px solid rgba(175, 184, 193, 0.3);
			}

			/* 括号内HTML内容样式 - 避免CSS渲染 */
			:deep(code.inline-html) {
				background-color: rgba(255, 193, 7, 0.1);
				color: #856404;
				padding: 2px 6px;
				border-radius: 4px;
				font-size: 0.875em;
				font-family: 'Fira Code', 'Monaco', 'Cascadia Code', 'Roboto Mono', 'Consolas', 'Courier New', monospace;
				font-weight: 500;
				border: 1px solid rgba(255, 193, 7, 0.3);
				white-space: nowrap;
				display: inline;
				/* 确保内容不会被解析为HTML */
				pointer-events: none;
				user-select: text;
			}

			:deep(pre) {
				margin: 12px 0;
				border-radius: 8px;
				overflow-x: auto;
				background-color: #f6f8fa;
				border: 1px solid #e1e4e8;
				box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

				/* highlight.js 代码块样式 */
				code.hljs {
					background: none !important;
					padding: 16px;
					display: block;
					font-size: 0.875em;
					line-height: 1.6;
					font-family: 'Fira Code', 'Monaco', 'Cascadia Code', 'Roboto Mono', 'Consolas', 'Courier New', monospace;
					color: #24292e;
					tab-size: 4;
					-moz-tab-size: 4;
					-o-tab-size: 4;
					white-space: pre;
					word-wrap: normal;
					overflow-wrap: normal;
				}

				/* 普通代码块（无语言标识） */
				code {
					background: none;
					padding: 16px;
					display: block;
					font-size: 0.875em;
					line-height: 1.6;
					font-family: 'Fira Code', 'Monaco', 'Cascadia Code', 'Roboto Mono', 'Consolas', 'Courier New', monospace;
				}
			}

			:deep(ul),
			:deep(ol) {
				margin: 4px 0;
				padding-left: 20px;
			}

			:deep(li) {
				margin: 2px 0;
			}

			:deep(blockquote) {
				border-left: 4px solid #ddd;
				padding-left: 12px;
				margin: 8px 0;
				color: #666;
			}

			:deep(table) {
				border-collapse: collapse;
				width: 100%;
				margin: 8px 0;
				font-size: 0.9em;

				th,
				td {
					border: 1px solid #ddd;
					padding: 6px 8px;
					text-align: left;
				}

				th {
					background-color: #f1f3f4;
					font-weight: 600;
				}
			}

			:deep(a) {
				color: #1890ff;
				text-decoration: none;

				&:hover {
					text-decoration: underline;
				}
			}
		}

		/* 元素修改显示样式 */
		.element-modify-display {
			margin: 8px 0;

			.user-text-normal {
				color: #333;
				font-size: 14px;
				line-height: 1.6;
				margin-bottom: 8px;
			}

			.selected-element-card {
				background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
				border: 1px solid #d9d9d9;
				border-radius: 8px;
				padding: 12px 16px;
				margin-top: 8px;
				max-height: 100px;
				overflow-y: auto;
				box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
				transition: all 0.3s ease;
				position: relative;

				&:before {
					content: '';
					position: absolute;
					top: 0;
					left: 0;
					width: 4px;
					height: 100%;
					background: linear-gradient(180deg, #1890ff 0%, #52c41a 100%);
				}

				&:hover {
					background: linear-gradient(135deg, #e6f7ff 0%, #d6f7ff 100%);
					border-color: #91d5ff;
					transform: translateY(-2px);
					box-shadow: 0 4px 16px rgba(24, 144, 255, 0.15);
				}

				.element-info-row {
					display: flex;
					align-items: center;
					gap: 8px;
					flex-wrap: wrap;

					.element-tag {
						color: #1890ff;
						font-weight: 700;
						font-size: 12px;
						text-transform: uppercase;
						padding: 4px 8px;
						background: rgba(24, 144, 255, 0.1);
						border: 1px solid rgba(24, 144, 255, 0.2);
						border-radius: 4px;
						transition: all 0.2s ease;
						letter-spacing: 0.5px;
					}

					.element-class {
						color: #f5222d;
						font-weight: 600;
						font-size: 12px;
						padding: 4px 8px;
						background: rgba(245, 34, 45, 0.1);
						border: 1px solid rgba(245, 34, 45, 0.2);
						border-radius: 4px;
						transition: all 0.2s ease;
						&:before {
							content: '.';
							font-weight: 700;
						}
					}

					.element-content {
						color: #595959;
						font-size: 13px;
						font-weight: 500;
						padding: 4px 8px;
						background: rgba(0, 0, 0, 0.04);
						border-radius: 4px;
						max-width: 200px;
						white-space: nowrap;
						overflow: hidden;
						text-overflow: ellipsis;
						transition: all 0.2s ease;
					}
				}

				&:hover .element-info-row {
					.element-tag {
						background: #1890ff;
						color: white;
						border-color: #1890ff;
						transform: scale(1.05);
					}

					.element-class {
						background: #f5222d;
						color: white;
						border-color: #f5222d;
						transform: scale(1.05);
					}

					.element-content {
						background: rgba(0, 0, 0, 0.08);
						color: #262626;
						transform: scale(1.02);
					}
				}

				/* 自定义滚动条样式 */
				&::-webkit-scrollbar {
					width: 6px;
				}

				&::-webkit-scrollbar-track {
					background: rgba(0, 0, 0, 0.1);
					border-radius: 3px;
				}

				&::-webkit-scrollbar-thumb {
					background: rgba(24, 144, 255, 0.3);
					border-radius: 3px;
					transition: background 0.3s ease;
				}

				&::-webkit-scrollbar-thumb:hover {
					background: rgba(24, 144, 255, 0.5);
				}
			}
		}


		.message-time {
			font-size: 11px;
			opacity: 0.6;
			margin-top: 4px;
			text-align: right;
		}
	}
}

/* 消息头像样式 */
.message-avatar-style {
	border: 2px solid #ff8c00 !important;
	box-shadow: 0 2px 8px rgba(255, 140, 0, 0.3) !important;
	transition: all 0.3s ease !important;

	&:hover {
		border-color: #ff7700 !important;
		box-shadow: 0 4px 12px rgba(255, 140, 0, 0.5) !important;
		transform: scale(1.05) !important;
	}
}

@keyframes spin {
	0% {
		transform: translateY(-50%) rotate(0deg);
	}
	100% {
		transform: translateY(-50%) rotate(360deg);
	}
}
</style>
